import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:background_downloader/background_downloader.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_download_plugin/utils/video/m3u8_downloader.dart';
import 'package:flutter_download_plugin/utils/video/video_utils.dart';
import 'package:flutter_hls_parser/flutter_hls_parser.dart';
import 'package:flutter_video_info/flutter_video_info.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';

class DownloadUtils {
  ///视频信息工具类
  static final videoInfo = FlutterVideoInfo();

  // static final m3u8DownloaderPlugin = M3u8DownloaderPlugin();

  ///记录上一次更新时间，主要是限制频繁更新
  static int lastUpdateTime = 0;

  ///初始化数据库相关的东西和
  static void initDownloadConfig() async {
    await FileDownloader().trackTasks();
    //m3u8专用下载器初始化
    M3u8Downloader().init();

    M3u8Downloader().setListener(
      onPrepared: (M3u8DownloaderTask task) {
        // LogUtils().logger.d("任务准备中${task}");
        notifyHomePage();
      },
      onStart: (M3u8DownloaderTask task, int totalBytes) {
        // LogUtils().logger.d("任务开始${task}");
        notifyHomePage();
      },
      onProgress: (M3u8DownloaderTask task, double progress, int downloadedBytes, int totalBytes) {
        // LogUtils().logger.d("下载中${task.directory}--${task.progress}");
        notifyHomePage();
      },
      onFailed: (M3u8DownloaderTask task, String msg) {
        // LogUtils().logger.d("下载失败${task.directory}");
        notifyHomePage();
      },
      onSuccess: (M3u8DownloaderTask task) {
        // LogUtils().logger.d("下载完成${task.directory}");
        notifyHomePage();
      },
      onPaused: (M3u8DownloaderTask task) {
        // LogUtils().logger.d("任务暂停${task.directory}");
        notifyHomePage();
      },
    );

    // await m3u8DownloaderPlugin.init(onDownloadProgress: (DownloadItem item) {
    //   // NotificationUtils.showProgressNotification(
    //   //     title: "${item.fileName} downloaded",
    //   //     body: item.downloadSizeString,
    //   //     payload: "",
    //   //     channelId: item.fileHash,
    //   //     channelName: item.url,
    //   //     maxProgress: 100,
    //   //     progress: item.percent.toInt());
    //   notifyHomePage();
    // }, onDownloadSuccess: (DownloadItem item) {
    //   // print("下载完成");
    //   NotificationUtils.showNotification(
    //     title: "${item.fileName} downloaded",
    //     body: item.downloadSizeString,
    //     payload: "",
    //     channelId: item.fileHash,
    //     channelName: item.url,
    //   );
    //   notifyHomePage();
    // }, onDownloadError: (DownloadItem item) {
    //   NotificationUtils.showNotification(title: "download error", body: item.url, payload: "", channelId: item.fileHash, channelName: item.url);
    //   notifyHomePage();
    // }, onDownloadStart: (DownloadItem item) {
    //   // print("下载开始");
    //   // NotificationUtils.showNotification(title: "start download", body: item.url, payload: "", channelId: item.fileHash, channelName: item.url);
    //   notifyHomePage();
    // }, onDownloadPending: (DownloadItem item) {
    //   notifyHomePage();
    // }, onDownloadPause: (DownloadItem item) {
    //   notifyHomePage();
    // }, onDownloadPrepare: (DownloadItem item) {
    //   notifyHomePage();
    // });
  }

  ///文件存的应用的目录，这里主要是获取通知的权限
  static Future<void> initNotification() async {
    // // const permissionType = PermissionType.notifications;
    // // var status = await FileDownloader().permissions.status(permissionType);
    // // if (status != PermissionStatus.granted) {
    // //   //通知权限不影响流程未获取到不做强制处理
    // //
    // //   // if (await FileDownloader().permissions.shouldShowRationale(permissionType)) {
    // //   //   await showRationaleDialog(permissionType); // Show a dialog with rationale
    // //   // }
    // //   // status = await FileDownloader().permissions.request(permissionType);
    // //   // debugPrint('Permission for $permissionType was $status');
    // //   return false;
    // // } else {
    //
    // FileDownloader().configureNotification(
    //     running: const TaskNotification('Downloading', 'file: {filename}'),
    //     complete: const TaskNotification('Download complete', 'file: {filename}'),
    //     error: const TaskNotification('Download failed', 'file: {filename}'),
    //     paused: const TaskNotification('Download paused', 'file: {filename}'),
    //     progressBar: true);
    //
    // // return true;
    // // }
  }

  ///判断是否是m3u8格式
  static bool isM3u8(String url) {
    url = url.toLowerCase();
    if (url.contains(".m3u8") || url.contains(".mpd") || url.contains(".m3u")) {
      return true;
    }
    return false;
  }

  ///根据分组查询全部任务
  static Future<List<CustomDownloadTask>> allRecords({
    String? group,
  }) async {
    // query the tracking database, returning a record for each task
    // group ??= "default";
    List<TaskRecord> records = await FileDownloader().database.allRecords(group: group);

    //把列表转出自定义的包装类
    List<CustomDownloadTask> allList = [];
    for (var record in records) {
      CustomDownloadTask data = await recordToBean(record);
      allList.add(data);
    }

    //获取m3u8的列表
    List<M3u8DownloaderTask> m3u8List = M3u8Downloader().getTaskQueue();
    for (var record in m3u8List) {
      CustomDownloadTask data = await recordM3u8ToBean(record);
      allList.add(data);
    }

    //筛选分组
    if (group != null) {
      for (int i = 0; i < allList.length; i++) {
        if (allList[i].group != group) {
          allList.removeAt(i);
          i--;
        }
      }
    }

    //倒序
    allList.sort((CustomDownloadTask a, CustomDownloadTask b) {
      return b.creationTime.compareTo(a.creationTime);
    });

    // 去除分页功能
    // List<TaskRecord> recordsBak;
    // if (size != null && records.length > size) {
    //   recordsBak = records.sublist(0, size);
    // } else {
    //   recordsBak = records;
    // }

    return allList;
  }

  ///根据分组查询全部任务(按最近时间)
  static Future<List<CustomDownloadTask>> allRecordsOlderThan(int sec, {String? group}) async {
    List<CustomDownloadTask> allList = [];

    // query the tracking database, returning a record for each task
    List<TaskRecord> records = await FileDownloader().database.allRecordsOlderThan(Duration(seconds: sec), group: group);
    for (var record in records) {
      CustomDownloadTask data = await recordToBean(record);
      allList.add(data);
    }
    //获取m3u8的列表
    List<M3u8DownloaderTask> m3u8List = M3u8Downloader().getTaskQueue();
    for (var record in m3u8List) {
      CustomDownloadTask data = await recordM3u8ToBean(record);
      allList.add(data);
    }

    //根据时间筛选
    for (int i = 0; i < m3u8List.length; i++) {
      if (m3u8List[i].creationTimeStamp < (DateTime.now().millisecondsSinceEpoch - (sec * 1000))) {
        m3u8List.removeAt(i--);
      }
    }

    for (var record in m3u8List) {
      CustomDownloadTask data = await recordM3u8ToBean(record);
      allList.add(data);
    }

    //筛选分组
    if (group != null) {
      for (int i = 0; i < allList.length; i++) {
        if (allList[i].group != group) {
          allList.removeAt(i);
          i--;
        }
      }
    }

    //倒序
    allList.sort((CustomDownloadTask a, CustomDownloadTask b) {
      return b.creationTime.compareTo(a.creationTime);
    });

    return allList;
  }

  ///根据分组查询全部任务(按最近时间)
  ///   [name] enqueued,,  running,,  complete,,  notFound,,  failed,,  canceled,,  waitingToRetry,,  paused;
  static Future<List<CustomDownloadTask>> allRecordsWithStatus(TaskStatus status, {String? group}) async {
    // query the tracking database, returning a record for each task
    List<CustomDownloadTask> allList = [];

    List<TaskRecord> recordAllList = [];
    //下载中特殊处理，包含入栈和下载中
    if (status == NotificationType.running) {
      List<TaskRecord> recordEnqueuedList = await FileDownloader().database.allRecordsWithStatus(TaskStatus.enqueued, group: group);
      List<TaskRecord> recordRunningList = await FileDownloader().database.allRecordsWithStatus(TaskStatus.running, group: group);
      recordAllList.addAll(recordEnqueuedList);
      recordAllList.addAll(recordRunningList);
    } else {
      recordAllList = await FileDownloader().database.allRecordsWithStatus(status, group: group);
    }

    for (var record in recordAllList) {
      CustomDownloadTask data = await recordToBean(record);
      allList.add(data);
    }

    //获取m3u8的列表
    List<M3u8DownloaderTask> m3u8List = M3u8Downloader().getTaskQueue();
    for (var record in m3u8List) {
      CustomDownloadTask data = await recordM3u8ToBean(record);
      allList.add(data);
    }
    //筛选状态
    for (int i = 0; i < m3u8List.length; i++) {
      TaskStatus m3u8Status = m3u8List[i].status;
      // print("==========================${m3u8Status}");

      if (status != m3u8Status) {
        m3u8List.removeAt(i--);
      } else {
        CustomDownloadTask data = await recordM3u8ToBean(m3u8List[i]);
        allList.add(data);
      }
    }

    //筛选分组
    if (group != null) {
      for (int i = 0; i < allList.length; i++) {
        if (allList[i].group != group) {
          allList.removeAt(i);
          i--;
        }
      }
    }

    //倒序
    allList.sort((CustomDownloadTask a, CustomDownloadTask b) {
      return b.creationTime.compareTo(a.creationTime);
    });

    return allList;
  }

  ///给视频文件附加上基础的信息
  static Future<CustomDownloadTask> attachVideoInfo(CustomDownloadTask data) async {
    try {
      // String filePath = data.filePath;

      //部分文件下载地址是没有后缀的，所以先不判断免得过滤掉需要的地址
      // if (!TextUtils.isVideoFile(filePath)) {
      //   return data;
      // }
      if (data.duration != null && data.fileSize != null) {
        return data;
      }

      VideoData? info = await videoInfo.getVideoInfo(data.filePath);
      if (info == null || info.filesize == null || info.filesize == 0) {
        return data;
      }

      if (info.duration != null) {
        var durationTime = VideoUtils.formatDuration(info != null ? info.duration! / 1000 : 0.0);
        data.durationTime = durationTime;
        data.duration = info.duration! / 1000;
      }

      data.title = info.title;
      data.width = info.width;
      data.height = info.height;
      data.fileSize = info.filesize;

      /// (0 - LandscapeRight)
      /// (90 - Portrait)
      /// (180 - LandscapeLeft)
      /// (270 - portraitUpsideDown)
      data.orientation = info.orientation;
    } catch (e) {
      print(e);
    }
    return data;
  }

  /// [taskId] 必须是唯一的。如果省略，将生成一个唯一的ID
  /// [url] 如果需要，应正确编码，可以包括查询参数
  /// [urlQueryParameters] 可以添加，并将附加到[url]，如果需要，必须正确编码
  /// [fileName] 要保存的文件的名称。如果省略，将生成一个随机文件名
  /// [headers] 可选的HTTP请求头映射
  /// [httpRequestMethod] 使用的HTTP请求方法（例如 GET, POST）
  /// [post] 如果设置，将使用POST而不是GET。Post必须是以下之一：
  /// - 一个String: POST请求，[post]作为主体，使用utf8编码
  /// - 一个Map: 将被jsonEncoded成一个String并设置为POST主体
  /// - 一个字节列表: 将使用String.fromCharCodes转换为String并设置为POST主体
  /// - 一个列表: 地图将被jsonEncoded成一个String并设置为POST主体
  ///
  /// [directory] 可选的目录名称，位于[fileName]之前，m3u8文件时次参数无效
  /// [group] 如果设置，允许不同组的不同回调或处理
  /// [updates] 请求的进度更新类型
  /// [requiresWiFi] 如果设置，将不会在WiFi可用之前开始下载。如果没有设置，可能会通过蜂窝网络开始下载，默认false
  /// [retries] 如果>0，将重试失败的下载这么多次
  /// [allowPause] 如果为true，允许暂停命令
  /// [priority] 范围0 <= priority <= 10，其中0最高，默认为5
  /// [metaData] 用户数据
  /// [displayName] 任务的易读名称
  /// [variantIndex] m3u8格式文件下载的变体索引
  static Future<void> download(
      {required List<dynamic> urlList,
      variantIndex = 0,
      String directory = "download",
      Updates updates = Updates.none,
      List<dynamic>? coverList,
      Map<String, String>? urlQueryParameters,
      String? fileName,
      Map<String, String>? headers,
      String? httpRequestMethod,
      String? post,
      String group = "default",
      bool? requiresWiFi,
      int? retries,
      bool? allowPause,
      int? priority,
      String? metaData,
      String? displayName,
      DateTime? creationTime}) async {
    // var status = await Permission.notification.status;
    // if (status.isDenied) {
    //   // We haven't asked for permission yet or the permission has been denied before, but not permanently.
    //   await Permission.notification.onDeniedCallback(() {
    //     // Your code
    //   }).onGrantedCallback(() {
    //     // Your code
    //     initNotification();
    //   }).onPermanentlyDeniedCallback(() {
    //     // Your code
    //   }).onRestrictedCallback(() {
    //     // Your code
    //   }).onLimitedCallback(() {
    //     // Your code
    //   }).onProvisionalCallback(() {
    //     // Your code
    //   }).request();
    // } else {
    //   initNotification();
    // }
    initNotification();

    List<DownloadTask> taskList = [];

    for (int i = 0; i < urlList.length; i++) {
      // String suffix = urlList[i].split('.').last;

      //是否是m3u8格式的视频
      if (isM3u8(urlList[i])) {
        ///m3u8的格式下载到本地后会自动转换成mp4的格式
        fileName ??= "${DateTime.now().millisecondsSinceEpoch.toString()}_$i.mp4";

        // downloadM3u8(url: urlList[i], groupName: group, fileName: fileName, displayName: displayName ?? "");

        M3u8Downloader().addDownloadTask(
          task: M3u8DownloaderTask(url: urlList[i], displayName: displayName ?? "", group: group, fileName: fileName),
          onMasterSelect: (List<Variant> variants) async {
            return variantIndex;
          },
        );
      } else {
        final task = await DownloadTask(
                // url:
                //     'https://v3-default.ixigua.com/adddefc80e9c68fe85c20e29fe22ac76/672341bb/video/tos/cn/tos-cn-ve-15/oQnBHkGrLCoDp2SNB79oACRBekeIEEQeANaC8I/?a=2011&ch=0&cr=0&dr=0&er=0&lr=unwatermarked&net=5&cd=0%7C0%7C0%7C0&cv=1&br=1710&bt=1710&cs=0&ds=4&ft=k7Fz7VVywfyRF38Pmo~pK7pswApEt8qZvrKyU5Tmto0g3cI&mime_type=video_mp4&qs=0&rc=Z2hmNzQ4NWQ0NzU0ZDhpZ0BpMztzanM5cnJndTMzNGkzM0BhMy1jM2I2NV4xNDUvY15eYSNoMF80MmRjLjZgLS1kLS9zcw%3D%3D&btag=80000e00008000&dy_q=1730360226&feature_id=46a7bb47b4fd1280f3d3825bf2b29388&l=2024103115370644F50387C7115CB16D7A',
                // urlQueryParameters: {'q': 'pizza'},
                // filename: "ffdfds.mp4",
                // directory: 'my_sub_directory',

                url: urlList[i],
                directory: directory,
                baseDirectory: BaseDirectory.applicationDocuments,
                urlQueryParameters: urlQueryParameters,
                filename: fileName,
                headers: headers,
                httpRequestMethod: httpRequestMethod,
                post: post,
                group: group,
                updates: updates,
                // request status and progress updates
                requiresWiFi: requiresWiFi ?? false,
                retries: retries ?? 0,
                allowPause: allowPause ?? true,
                priority: priority ?? 5,
                metaData: metaData ?? "",
                displayName: displayName ?? fileName ?? VideoUtils.getFileName(urlList[i]),
                creationTime: creationTime)
            .withSuggestedFilename(unique: true);

        taskList.add(task);
      }
    }
    for (int i = 0; i < urlList.length; i++) {
      //根据url请求附上任务的封面信息
      attachTaskCover(urlList[i]);
    }
    if (taskList.isNotEmpty) {
      // download the batch
      Future<Batch> result = FileDownloader().downloadBatch(taskList, batchProgressCallback: (succeeded, failed) {
        // print('Completed ${succeeded + failed} out of , $failed failed');
        // LogUtils().logger.d('Completed ${succeeded + failed} out of , $failed failed');
        notifyHomePage();
      }, taskProgressCallback: (TaskProgressUpdate update) {
        // print(update.progress);
        if (kDebugMode) {
          print("${update.task.displayName}:Update ${update.progress}");
        }

        //记录上次的更新时间并限制回调更新的频率
        int now = DateTime.now().millisecondsSinceEpoch;
        if (now - lastUpdateTime > 2000) {
          lastUpdateTime = now;
          notifyHomePage();
        }
      }, taskStatusCallback: (TaskStatusUpdate update) {
        //框架问题在加入到队列的刚开始里面查询下载任务队列不会有值，所以这里做个延时刷新
        if (update.status == TaskStatus.enqueued) {
          Timer(const Duration(milliseconds: 100), () {
            notifyHomePage();
          });
        } else if (update.status == TaskStatus.complete) {
        } else if (update.status == TaskStatus.failed) {}
      });
    }

    List<dynamic> list = [];
    notifyHomePage();

    // Batch batch = await result;
    //
    // List<Task> batchTaskList = batch.tasks;
    //
    // batchTaskList.forEach((record) {
    //   list.add(taskToCustomBean(record));
    // });
    //
    // return list;

    // print("==========");
    // print(result.tasks.first.filename);
    // String path = await result.tasks.first.filePath(withFilename: result.tasks.first.filename);
    // print(path);

    // query the tracking database, returning a record for each task
    // final records = await FileDownloader().database.allRecords();
    //
    // records.forEach((record) {
    //   print('Task ${record.taskId} status is ${record.status}');
    //   if (record.status == TaskStatus.running) {
    //     print('-- progress ${record.progress * 100}%');
    //     print('-- file size ${record.expectedFileSize} bytes');
    //   }
    // });
  }

  ///附加封面信息
  static void attachTaskCover(String url) async {
    String key = "downloadFileInfo${VideoUtils.generateMd5(url)}";
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    //已经加载过不重复加载
    if (sharedPreferences.containsKey(key)) {
      return;
    }
    String filePath = await VideoUtils.getVideoCoverByUrl(url: url);

    //绑定cover
    dynamic info = {"originalURL": url, "cover": filePath};
    sharedPreferences.setString(key, jsonEncode(info));
  }

  ///删除任务的cover信息
  static Future<void> deleteCover(String url) async {
    String key = "downloadFileInfo${VideoUtils.generateMd5(url)}";
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    String? json = sharedPreferences.getString(key);
    if (json != null) {
      Map map = jsonDecode(json);
      String cover = map.containsKey("cover") ? map['cover'] : "";
      File file = File(cover);

      if (file.existsSync()) {
        file.deleteSync();
      }
    }
    sharedPreferences.remove(key);
  }

  ///暂停所有
  static Future<bool> pauseAll() async {
    M3u8Downloader().pauseAllDownload();
    List<TaskRecord> records = await FileDownloader().database.allRecords();
    for (TaskRecord record in records) {
      await FileDownloader().pause(DownloadTask(url: record.task.url));
      // await FileDownloader().cancelTaskWithId(record.taskId);
    }
    return true;
  }

  ///暂停任务
  static Future<bool> pause(String url) async {
    M3u8Downloader().pauseDownload(url: url);
    return await FileDownloader().pause(DownloadTask(url: url));
    // return await FileDownloader().cancelTaskWithId(taskId);
  }

  ///恢复下载任务
  static Future<bool> resume(String url) async {
    M3u8Downloader().resumeDownload(url: url);
    return await FileDownloader().resume(DownloadTask(url: url));
  }

  ///恢复下载任务
  static Future<bool> resumeAll() async {
    M3u8Downloader().resumeAllDownload();
    List<TaskRecord> records = await FileDownloader().database.allRecords();
    for (TaskRecord record in records) {
      await FileDownloader().resume(DownloadTask(url: record.task.url));
    }
    return true;
  }

  /// 将字符串转换为TaskStatus
  static TaskStatus stringToTaskStatus(String status) {
    status = status.replaceAll("TaskStatus.", "");

    switch (status) {
      case 'enqueued':
        return TaskStatus.enqueued;
      case 'running':
        return TaskStatus.running;
      case 'complete':
        return TaskStatus.complete;
      case 'notFound':
        return TaskStatus.notFound;
      case 'failed':
        return TaskStatus.failed;
      case 'canceled':
        return TaskStatus.canceled;
      case 'waitingToRetry':
        return TaskStatus.waitingToRetry;
      case 'paused':
        return TaskStatus.paused;
      default:
        return TaskStatus.notFound;
    }
  }

  ///框架的record对象转换
  static Future<CustomDownloadTask> recordToBean(TaskRecord record) async {
    String filePath = await record.task.filePath(withFilename: record.task.filename);
    CustomDownloadTask data = CustomDownloadTask(
      taskId: record.taskId,
      status: record.status.toString(),
      progress: record.progress,
      expectedFileSize: record.expectedFileSize,
      fileName: record.task.filename,
      filePath: filePath,
      displayName: record.task.displayName,
      group: record.task.group,
      metaData: record.task.metaData,
      priority: record.task.priority,
      url: record.task.url,
      creationTime: DateFormat(VideoUtils.YMD_HMS).format(record.task.creationTime),
      directory: record.task.directory,
    );

    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    String key = "downloadFileInfo${VideoUtils.generateMd5(data.url)}";

    String json = sharedPreferences.getString(key) ?? "";

    ///补充上封面等信息
    if (json.isNotEmpty) {
      Map map = jsonDecode(json);
      data.cover = map.containsKey("cover") ? map['cover'] : "";
      data.originalURL = map.containsKey("originalURL") ? map['originalURL'] : "";
    }

    ///附加视频信息
    data = await attachVideoInfo(data);

    if (data.fileSize != null) data.fileSizeStr = VideoUtils.formatFileSize(data.fileSize!);
    return data;
  }

  ///框架的m3u8对象转换
  static Future<CustomDownloadTask> recordM3u8ToBean(M3u8DownloaderTask record) async {
    String filePath = record.filePath;
    DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(record.creationTimeStamp);
    CustomDownloadTask data = CustomDownloadTask(
        //m3u8没有id所以使用但是url时唯一的所以使用url转md5作为任务id
        taskId: record.url,
        status: record.status.toString(),
        progress: record.progress,
        expectedFileSize: record.totalLength,
        fileName: record.fileName,
        filePath: filePath,
        displayName: record.displayName,
        group: record.group,
        metaData: record.url,
        priority: 5,
        url: record.url,
        originalURL: record.url,
        creationTime: DateFormat(VideoUtils.YMD_HMS).format(dateTime),
        directory: "",
        //框架不能配置这个
        totalSpeed: record.totalSpeed);

    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    String key = "downloadFileInfo${VideoUtils.generateMd5(data.url)}";
    String json = sharedPreferences.getString(key) ?? "";

    ///补充上封面等信息
    if (json.isNotEmpty) {
      Map map = jsonDecode(json);
      data.cover = map.containsKey("cover") ? map['cover'] : "";
      data.originalURL = map.containsKey("originalURL") ? map['originalURL'] : "";
    }

    ///附加视频信息
    data = await attachVideoInfo(data);

    if (data.fileSize != null) data.fileSizeStr = VideoUtils.formatFileSize(data.fileSize!);
    return data;
  }

  //m3u8的任务状态转为公用下载的任务状态
  //0;       //默认状态
  // -1;      //下载排队
  // 1;       //下载准备中
  // 2;         //开始下载
  // 3;   //下载中
  // 4;    //视频可以边下边播
  // 5;       //下载完成
  // 6;         //下载出错
  // 7;         //下载暂停
  // 8;        //空间不足
  static TaskStatus m3u8StatusToTaskStatus(int status) {
    switch (status) {
      case 0:
        return TaskStatus.enqueued;
      case -1:
      case 1:
        return TaskStatus.enqueued;
      case 2:
      case 3:
      case 4:
        return TaskStatus.running;
      case 5:
        return TaskStatus.complete;
      case 6:
        return TaskStatus.failed;
      case 7:
        return TaskStatus.paused;
      case 8:
        return TaskStatus.failed;
      default:
        return TaskStatus.notFound;
    }
  }

  ///框架的task对象转换为自定义的包装task对象
  static CustomDownloadTask taskToCustomBean(Task task) {
    // dynamic item = {
    //   "taskId": task.taskId,
    //   "filename": task.filename,
    //   "directory": task.directory,
    //   "group": task.group,
    //   "displayName": task.displayName,
    //   "metaData": task.metaData,
    //   "priority": task.priority,
    //   "url": task.url,
    //   "creationTime": task.creationTime,
    //   "headers": task.headers,
    //   "httpRequestMethod": task.httpRequestMethod,
    //   "post": task.post,
    //   "requiresWiFi": task.requiresWiFi,
    //   "retries": task.retries,
    //   "allowPause": task.allowPause,
    // };

    CustomDownloadTask item = CustomDownloadTask(
      taskId: task.taskId,
      fileName: task.filename,
      directory: task.directory,
      group: task.group,
      displayName: task.displayName,
      metaData: task.metaData,
      priority: task.priority,
      url: task.url,
      creationTime: DateFormat(VideoUtils.YMD_HMS).format(task.creationTime),
      headers: task.headers,
      httpRequestMethod: task.httpRequestMethod,
      post: task.post,
      requiresWiFi: task.requiresWiFi,
      retries: task.retries,
      allowPause: task.allowPause,
    );

    return item;
  }

  ///取消下载任务
  static Future<bool> cancelTasksWithIds(List<dynamic> taskIds) async {
    List<String> taskIds2 = taskIds.map((e) => e.toString()).toList();

    bool flag = await FileDownloader().cancelTasksWithIds(taskIds2);

    for (String url in taskIds) {
      //任务id就是下载的url
      M3u8Downloader().pauseDownload(url: url);
    }
    notifyHomePage();
    return flag;
  }

  ///清除记录
  static Future<void> deleteTasksByIds(List<dynamic> taskIds, {deleteFiles = true}) async {
    List<String> taskIds2 = taskIds.map((e) => e as String).toList();

    bool flag = await FileDownloader().cancelTasksWithIds(taskIds2);

    List<TaskRecord> records = await FileDownloader().database.allRecords();
    //删除源文件
    if (deleteFiles) {
      for (TaskRecord t in records) {
        if (taskIds2.indexWhere((id) => id == t.taskId) >= 0) {
          File file = File(await t.task.filePath());
          if (file.existsSync()) {
            file.deleteSync(recursive: true);
          }
          //删除缓存的封面信息
          deleteCover(t.task.url);
        }
      }
    }
    //删除记录
    await FileDownloader().database.deleteRecordsWithIds(taskIds2);

    //m3u8删除
    for (String url in taskIds) {
      //任务id就是下载的url
      M3u8Downloader().deleteTask(url: url, deleteFiles: deleteFiles);
      deleteCover(url);
    }

    notifyHomePage();
  }

  ///清除所有记录
  static Future<void> deleteAll({
    deleteFiles = true,
  }) async {
    List<CustomDownloadTask> list = await allRecords();
    for (CustomDownloadTask task in list) {
      deleteCover(task.url);
    }

    // query the tracking database, returning a record for each task
    List<TaskRecord> records = await FileDownloader().database.allRecords();
    for (TaskRecord record in records) {
      // await FileDownloader().cancelTaskWithId(record.task.taskId);
      await FileDownloader().cancelTaskWithId(record.task.taskId);
    }

    await FileDownloader().database.deleteAllRecords();

    // m3u8DownloaderPlugin.deleteAllDownload(shouldDeleteSourceFile: true);
    M3u8Downloader().deleteAllTask(deleteFiles: deleteFiles);

    notifyHomePage();
  }

  ///更新数据刷新
  static void notifyHomePage() {}

  ///[dir]文件夹的名称 [fileName]保存文件的名称
  static void downloadM3u8({required String url, String groupName = 'default', String displayName = "", required String fileName}) async {
    // m3u8DownloaderPlugin.startDownload(url, groupName: groupName);

    // Timer(const Duration(seconds: 30), () {
    //   m3u8DownloaderPlugin.deleteDownload(url, true);
    // });
  }
}

///自定义包装的一层下载任务对象
class CustomDownloadTask {
  String taskId;
  String directory;
  String group;
  String? displayName;
  String? metaData;
  int? priority;
  String url;
  String creationTime;
  Map<String, String>? headers;
  String? httpRequestMethod;
  String? post;
  bool? requiresWiFi;
  int? retries;
  bool? allowPause;

  String status;
  double progress;
  int expectedFileSize;
  String fileName;
  String filePath;

  ///总计下载速度（所有分片数据速度之和）,下载普通文件时没有速度的值，只有下载m3u8文件时才有速度
  int totalSpeed;

  ///额外的附加信息
  String? cover;
  String? originalURL;
  int? fileSize;
  String? fileSizeStr;
  String? title;
  int? width;
  int? height;
  String? durationTime;
  double? duration;
  int? orientation;

  CustomDownloadTask({
    required this.taskId,
    required this.fileName,
    required this.directory,
    required this.group,
    this.displayName,
    this.metaData,
    this.priority,
    required this.url,
    required this.creationTime,
    this.headers,
    this.httpRequestMethod,
    this.post,
    this.requiresWiFi,
    this.retries,
    this.allowPause,
    this.status = "enqueued",
    this.progress = 0,
    this.expectedFileSize = 0,
    this.filePath = "",
    this.cover,
    this.originalURL,
    this.fileSize,
    this.fileSizeStr,
    this.title,
    this.width,
    this.height,
    this.durationTime,
    this.duration,
    this.orientation,
    this.totalSpeed = 0,
  });

  factory CustomDownloadTask.fromJson(Map<String, dynamic> json) {
    return CustomDownloadTask(
      taskId: json['taskId'] ?? "",
      fileName: json['filename'] ?? "",
      directory: json['directory'] ?? "",
      group: json['group'] ?? "",
      displayName: json['displayName'] ?? "",
      metaData: json['metaData'] ?? "",
      priority: json['priority'] ?? 0,
      url: json['url'] ?? "",
      creationTime: json['creationTime'] ?? "",
      headers: json['headers'] ?? <String, String>{},
      httpRequestMethod: json['httpRequestMethod'] ?? "",
      post: json['post'] ?? "",
      requiresWiFi: json['requiresWiFi'] ?? false,
      retries: json['retries'] ?? 0,
      allowPause: json['allowPause'] ?? true,
      status: json['status'] ?? "enqueued",
      progress: json['progress'] ?? 0,
      expectedFileSize: json['expectedFileSize'] ?? "",
      filePath: json['filePath'] ?? "",
      cover: json['cover'] ?? "",
      originalURL: json['originalURL'] ?? "",
      fileSize: json['fileSize'] ?? "",
      fileSizeStr: json['fileSizeStr'] ?? "",
      title: json['title'] ?? "",
      width: json['width'] ?? "",
      height: json['height'] ?? "",
      durationTime: json['durationTime'] ?? "",
      duration: json['duration'] ?? "",
      orientation: json['orientation'] ?? "",
      totalSpeed: json['totalSpeed'] ?? 0,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'taskId': taskId,
      'filename': fileName,
      'directory': directory,
      'group': group,
      'displayName': displayName,
      'metaData': metaData,
      'priority': priority,
      'url': url,
      'creationTime': creationTime,
      'headers': headers,
      'httpRequestMethod': httpRequestMethod,
      'post': post,
      'requiresWiFi': requiresWiFi,
      'retries': retries,
      'allowPause': allowPause,
      'status': status,
      'progress': progress,
      'expectedFileSize': expectedFileSize,
      'filePath': filePath,
      'cover': cover,
      'originalURL': originalURL,
      'fileSize': fileSize,
      'fileSizeStr': fileSizeStr,
      'title': title,
      'width': width,
      'height': height,
      'durationTime': durationTime,
      'duration': duration,
      'orientation': orientation,
      'totalSpeed': totalSpeed,
    };
  }
}
